﻿//基本用法
var Calculator = function (eq) {
    //这里可以申明私有成员
    var eqCtl = document.getElementById(eq);
    return {
        //暴露公开的成员
        add: function (x, y) {
            var val = x + y;
            eqCtl.innerHTML = val;
        }
    };
};
//匿名闭包
(function () {
    // ... 所有的变量和function都在这里声明，并且作用域也只能在这个匿名闭包里
    // ...但是这里的代码依然可以访问外部全局的对象
}());
//基本Module模式
var blogModule = (function () {
    var my = {}, privateName = "博客园";
    function privateAddTopic(data) {
        //这里是内部处理代码
    }
    my.Name = privateName;
    my.AddTopic = function (data) {
        privateAddTopic(data);
    };
    return my;
}());
//扩展
/*
Module模式的一个限制就是所有的代码都要写在一个文件，但是在一些大型项目里，
将一个功能分离成多个文件是非常重要的，因为可以多人合作易于开发
*/
var blogModule = (function (my) {
    my.AddPhoto = function () {
        //添加内部代码
    };
    return my;
}(blogModule));
//松耦合扩展
var blogModule = (function (my) {
    //添加一些功能
    return my;
}(blogModule || {}));
//紧耦合扩展
var blogModule = (function (my) {
    var oldAddPhotoMethod = my.AddPhoto;
    my.AddPhoto = function () {
        //重载方法，依然可通过oldAddPhotoMethod调用旧的方法。
    };
}(blogModule));
//克隆与继承
var blogModule = (function (old) {
    var my = {}, key;
    for (key in old) {
        if (old.hasOwnProperty(key)) {
            my[key] = old[key];
        }
    }
    var oldAddPhotoMethod = old.AddPhoto;
    my.AddPhoto = function () {
        //克隆以后，进行重写，当然可以继续调用oldAddPhotoMethod方法。
    };
}(blogModule));
//跨文件共享私有对象
/*
如果一个module分割到多个文件的话，每个文件需要保证一样的结构，
也就是说每个文件匿名函数里的私有对象都不能交叉访问，
那如果我们非要使用，那怎么办呢？
*/
var blogModule = (function (my) {
    var _private = my._private = my._private || {},
         _seal = my._seal = my._seal || function () {
             delete my._private;
             delete my._seal;
             delete my._unseal;
         },
         _unseal = my._unseal = my._unseal || function () {
             my._private = _private;
             my._seal = _seal;
             my._unseal = _unseal;
         };
    return my;
}(blogModule || {}));
//子模块
blogModule.CommentSubModule = (function () {
    var my = {};
    return my;
}());
/*
    Facade模式
    调用方式module.facade({run:true,val:10});
*/
var module = (function () {
    var _private = {
        i: 5,
        get: function () {
            console.log('current value:' + this.i);
        },
        set: function (val) {
            this.i = val;
        },
        run: function () {
            console.log("running");
        },
        jump: function () {
            console.log("jumping");
        }
    };
    return {
        facade: function (args) {
            _private.set(args.val);
            _private.get();
            if (args.run) {
                _private.run();
            }
        }
    };
}());